package PosterGenerate

import (
	"errors"
	"flag"
	"github.com/golang/freetype"
	"github.com/skip2/go-qrcode"
	"golang.org/x/image/font"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"io/ioutil"
	"log"
	"os"
)

type Config struct {
	qrCodeSize   int         // 二维码大小
	fontWidth    int         // 文字长度，如果不设置的话默认以12.5个像素来算一个字符串的宽度
	fontHeight   int         // 文字高度，如果不设置的话默认 24
	fontSize     float64     // 文字字体大小，如果不设置的话默认 20
	text         string      // 文字
	qrcodeUrl    string      // 二维码中的链接
	saveFilePath string      // 图片保存路径
	fontFilePath string      // 字体文件路径路径
	fontColor    color.Color // 字体颜色
	fontBgColor  color.Color // 字体背景颜色
}

// 必须传入字体文件路径
func New(fontFilePath string) *Config {
	return &Config{
		qrCodeSize:   256,
		fontHeight:   24,
		fontSize:     20,
		fontFilePath: fontFilePath,
		fontBgColor:  nil,
		fontColor:    color.RGBA{0, 0, 0, 255},
	}
}

// 设置 二维码大小
func (c *Config) SetQrcodeSize(size int) {
	c.qrCodeSize = size
}

// 设置 字体颜色
func (c *Config) SetFontColor(color color.Color) {
	c.fontColor = color
}

// 设置 字体背景颜色
func (c *Config) SetFontBgColor(color color.Color) {
	c.fontBgColor = color
}

// 设置 文字长度
func (c *Config) SetFontWidth(width int) {
	c.fontWidth = width
}

// 设置 文字高度
func (c *Config) SetFontHeight(height int) {
	c.fontHeight = height
}

// 设置 文字字体大小
func (c *Config) SetFontSize(size float64) {
	c.fontSize = size
}

// 创建二维码
func (c *Config) createQrCode(content string) (img image.Image, err error) {
	var qrCode *qrcode.QRCode

	qrCode, err = qrcode.New(content, qrcode.Highest)

	if err != nil {
		return nil, errors.New("创建二维码失败")
	}
	qrCode.DisableBorder = true

	img = qrCode.Image(c.qrCodeSize)

	return img, nil
}

// 渲染文字
func (c *Config) fontRender(jpg *image.RGBA, text string) {
	var (
		dpi      = flag.Float64("dpi", 72, "screen resolution in Dots Per Inch")
		fontfile = flag.String("fontfile", c.fontFilePath, "filename of the ttf font")
		hinting  = flag.String("hinting", "none", "none | full")
		size     = flag.Float64("size", c.fontSize, "font size in points")
		//spacing  = flag.Float64("spacing", 1.5, "line spacing (e.g. 2 means double spaced)")
		// wonb     = flag.Bool("whiteonblack", false, "white text on a black background") // 水印
	)
	/*
		var texts = []string{
			"1232131231232",
		}*/
	flag.Parse()
	fontBytes, err := ioutil.ReadFile(*fontfile)
	if err != nil {
		log.Println(err)
		return
	}
	f, err := freetype.ParseFont(fontBytes)
	if err != nil {
		log.Println(err)
		return
	}
	//ruler := color.RGBA{0xdd, 0xdd, 0xdd, 0xff}
	//if *wonb {
	//	fg, bg = image.White, image.Black
	//	ruler = color.RGBA{0x22, 0x22, 0x22, 0xff}
	//}

	// 设置图片背景
	if c.fontBgColor != nil {
		draw.Draw(jpg, jpg.Bounds(), image.NewUniform(c.fontBgColor), image.ZP, draw.Src)
	}
	fy := freetype.NewContext()
	fy.SetDPI(*dpi)
	fy.SetFont(f)
	fy.SetFontSize(*size)
	fy.SetClip(jpg.Bounds())
	fy.SetDst(jpg)
	//设置字体颜色(黑色)
	fy.SetSrc(image.NewUniform(c.fontColor))

	switch *hinting {
	default:
		fy.SetHinting(font.HintingNone)
	case "full":
		fy.SetHinting(font.HintingFull)
	}

	// Draw the text.
	/*
		pt := freetype.Pt(10, 10+int(c.PointToFixed(*size)>>6))
		for _, s := range texts {
			_, err = c.DrawString(s, pt)
			if err != nil {
				log.Println(err)
				return
			}
			pt.Y += c.PointToFixed(*size * *spacing) // 计算下一行偏移
		}*/
	_, err = fy.DrawString(text, freetype.Pt(0, int(fy.PointToFixed(*size)>>6)))
}

// 创建文字图片
func (c *Config) createFont(text string) *image.RGBA {
	width := int(float64(len(text)) * 12.5)
	if c.fontWidth != 0 {
		width = c.fontWidth
	}
	// 新建一个存放文字的画布，这里的 x1 和 y1 是 图片的宽和高，请按实际设置
	fontjpg := image.NewRGBA(image.Rect(0, 0, width, c.fontHeight))
	// 渲染文字
	c.fontRender(fontjpg, text)

	return fontjpg
}

// qrcodeUrl : 二维码内容，一般是地址
// saveFilePath 图片保存路径
// bgRect 海报大小
// text 文本内容
// qrcodePt 二维码位置
// fontPt 文本位置
// fontColor 字体颜色
// fontBgColor 字体背景颜色
func (c *Config) Create(qrcodeUrl, saveFilePath, text string, bgRect image.Rectangle,
	qrcodePt, fontPt image.Point) error {
	qrcodeImg, err := c.createQrCode(qrcodeUrl)

	if err != nil {
		return err
	}
	// 打开要保存的文件
	saveFile, err := os.Create(saveFilePath)
	if err != nil {
		return err
	}
	// 自动回收
	defer saveFile.Close()
	// 建一个背景画布
	bgjpg := image.NewRGBA(bgRect)
	// 创建一个带有文字的画布
	fontjpg := c.createFont(text)
	// 压入二维码，image.Pt(0, 0) 这里按实际坐标传入
	draw.Draw(bgjpg, qrcodeImg.Bounds().Add(qrcodePt), qrcodeImg, qrcodeImg.Bounds().Min, draw.Src)
	// 压入文字，image.Pt(0, 0)  这里按实际坐标传入
	draw.Draw(bgjpg, fontjpg.Bounds().Add(fontPt), fontjpg, image.ZP, draw.Over) // draw.Over 模式

	return png.Encode(saveFile, bgjpg)
}
